'''
Created on Jan 9, 2013

@author: Dan
'''
from Quoridor_game import WHITE, TIE
from game_agent import GameAgent
from quoridor_ab import IDAnytimeAlphaBeta
from heuristic import UTILITIES
import random
import time
from improving_game import improvedQuoridorState2

PAUSES = False

  

def moveFuncImprove2(self, game_state):
        temp = improvedQuoridorState2(0,game_state, True)
        action = self.alphaBeta.search(temp)
        
        if (PAUSES):
            raw_input('enter to continue...')
        
        return action
    
class DummyAgent(GameAgent):
    def move(self, game_state):
        actions = game_state.getSuccessors().keys()        
        actionNdx = random.randrange(len(actions))
        action = actions[actionNdx]
        
        if (PAUSES):
            raw_input('enter to continue...')
        
        return action
    
    def setup(self, player, game_state, turn_time_limit, setup_time_limit):
        random.seed()
        
        print 'Setup for Dummy player: ' + player
   
class AlphaBetaAgent(GameAgent):
    def __init__(self, w = None, depth = 100):
        self.depth = depth
        self.w = w
        
    def move(self, game_state):
        action,depth = self.alphaBeta.search(game_state)
        
        if (PAUSES):
            raw_input('enter to continue...')
        
        return action,depth
    
    def setup(self, player, game_state, turn_time_limit, setup_time_limit):
        self.player = player
        u = lambda state: self.utility(state)
        self.alphaBeta = IDAnytimeAlphaBeta(self.player, self.depth, u, turn_time_limit, self.w)

    #this is in-fact the heuristic value. In this case the heuristic is not very helpful, play with it and see why... 
    def utility(self, state):
        winner = state.getWinner()
        if winner is None:
            whiteDistance = 0
            for posW in state.locationsW:
                if posW != None: 
                    whiteDistance += (state.brdSize - 1 - posW[0])
                    whiteDistance += (posW[1] / 10.0)
            
            blackDistance = 0
            for posB in state.locationsB:
                if posB != None: 
                    blackDistance += posB[0]
                    blackDistance += (posB[1] / 10.0) 
            
            utilityValW = blackDistance - whiteDistance
            if self.player == WHITE:
                return utilityValW
            else:
                return -utilityValW            
            
        elif winner == self.player:
            return 100000
        elif winner == TIE:
            return 0
        else:
            return -100000
        
class AlphaBetaAgentImprovedQuoridorState2(AlphaBetaAgent):   
    def __init__(self, w = None, depth = 100,surroundingArea = 3):
        AlphaBetaAgent.__init__(self, w, depth)
        self.surroundingArea = surroundingArea
    def move(self, game_state):
        return moveFuncImprove2(self, game_state)
    
         
class MultiUtilityAgent(AlphaBetaAgent):
    '''
    agent that his utility check the number of rows to the goal
    '''
    def __init__(self, w = None, depth = 100):
        self.w = w
        self.utilites = UTILITIES
        self.utilites_weight = [1,1,1,1]
        AlphaBetaAgent.__init__(self, w, depth)
        
    def setup(self, player, game_state, turn_time_limit, setup_time_limit):
        print "setup for MultiUtilityAgent"
        self.player = player
        u = lambda state: self.utility(state)
        self.alphaBeta = IDAnytimeAlphaBeta(self.player, self.depth, u, turn_time_limit,self.w)
        
    def utility(self, state):
        tempVal = 0;
        for i in range(len(self.utilites)):
            if self.utilites_weight[i] > 0:
                tempVal += self.utilites_weight[i] * self.utilites[i](self,state)
                tempVal = tempVal +  random.uniform(-1,1)/100000
        return tempVal 

class MultiUtilityAgentImprovedQuoridorState2(MultiUtilityAgent):
    def __init__(self, w, depth,surroundingArea = 3):
        MultiUtilityAgent.__init__(self, w, depth)
        self.surroundingArea = surroundingArea
    def move(self, game_state):
        return moveFuncImprove2(self, game_state)

class multiAgentUser(MultiUtilityAgent):
    def __init__(self,utils,weights, w = None, depth = 100):
        MultiUtilityAgent.__init__(self,w,depth)
        self.utilites = utils
        self.utilites_weight = weights

 
class multiAgentUserImprovedQuoridorState2(multiAgentUser):
    def __init__(self, utils, weights, w = None, depth= 100, surroundingArea = 3):
        multiAgentUser.__init__(self, utils, weights, w, depth)
        self.surroundingArea = surroundingArea
    def move(self, game_state):
        return moveFuncImprove2(self, game_state) 
            
          
class multiFinalAgent10b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [1,0]
        
class multiFinalAgent11b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [1,1]
        
class multiFinalAgent12b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [1,2]

class multiFinalAgent21b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1]
        
        
class multiFinalAgent210b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.1,1]
        self.utilites_weight = [2,1,0]

class multiFinalAgent211b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.1,0.1]
        self.utilites_weight = [2,1,0.1]
        
class multiFinalAgent213b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.3,0.4]
        self.utilites_weight = [2,1,0.3]

class multiFinalAgent214b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.4]

class multiFinalAgent212b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,0.5,0.2,0.3]

##new based on multiFinalAgent214b
class multiFinalAgent2141b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.4,0.1] 
        self.utilites_weight = [2,1,0.2]
        
class multiFinalAgent216b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.6]

class multiFinalAgent218b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.8]

class multiFinalAgent2110b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,1]
        
class multiFinalAgent2112b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,1.2]
  
class multiFinalAgent2120b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,2]
 
class multiFinalAgent228b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,2,0.8]
        
class multiFinalAgent2142b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.4,0.2] 
        
class multiFinalAgent2150b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.5,0] 
class multiFinalAgent2131b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.3,0.1] 
        
class multiFinalAgent213505b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1,0.35,0.05]      
        

class multiFinalAgent2158b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1.5,0.8]
  

class multiFinalAgent258b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,0.5,0.8] 

class multiFinalAgent238b(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,0.3,0.8]   
        
class multiFinalAgent2158bb(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1.5,0.8,0]
        
    
class competitionAgent(MultiUtilityAgentImprovedQuoridorState2):
    def __init__(self, w = None, depth = 100,surroundingArea = 0):
        MultiUtilityAgentImprovedQuoridorState2.__init__(self,w,depth,surroundingArea)
        self.utilites_weight = [2,1.5,0.8]       

AGENTS = {
    "multiFinalAgent218b"       :   multiFinalAgent218b,
    "multiFinalAgent2158b"       :   multiFinalAgent2158b,
}
